package com.k8.registry.impl;

import com.k8.common.event.Event;
import com.k8.common.event.EventDeployer;
import com.k8.common.factroy.BeanFactory;
import com.k8.common.util.ObjectUtil;
import com.k8.registry.FailBackRegistry;
import com.k8.registry.listener.InstanceListener;
import com.k8.rpc.metadata.AppMetaData;
import com.k8.rpc.url.ApiSignature;
import com.k8.rpc.url.URL;

import java.util.List;

public abstract class ListenerRegistry extends FailBackRegistry {
    private RegistryEventDeployerWrapper registryEventDeployerWrapper;
    EventDeployer eventDeployer;

    public ListenerRegistry(URL url, BeanFactory beanFactory) {
        super(url, beanFactory);
        this.eventDeployer = beanFactory.getBean(EventDeployer.class);
        ObjectUtil.checkNotNull(this.eventDeployer, "EventDeployer is not register in beanFactory");
        this.registryEventDeployerWrapper = new RegistryEventDeployerWrapper(eventDeployer);
    }

    @Override
    protected final List<AppMetaData> getRemoteAppInstancesAndSubscribe(String mapping, ApiSignature apiSignature, URL registryConfigUrl, URL baseProtocolUrl) {
        return doGetRemoteAppInstancesAndSubscribe(mapping, apiSignature, registryConfigUrl, baseProtocolUrl, registryEventDeployerWrapper);
    }


    abstract protected List<AppMetaData> doGetRemoteAppInstancesAndSubscribe(String mapping, ApiSignature apiSignature, URL registryConfigUrl, URL baseProtocolUrl, RegistryEventDeployerWrapper registryEventDeployerWrapper);

    /**
     * 不同类型的注册中心实现要返回一个该监听器,从而发布{@link InstanceListener.InstanceEvent}事件以供NotifyListener处理
     */
    public static class RegistryEventDeployerWrapper {
        private EventDeployer eventDeployer;

        public RegistryEventDeployerWrapper(EventDeployer eventDeployer) {
            this.eventDeployer = eventDeployer;
        }

        public void publish(Event event) {
            eventDeployer.publishEvent(event);
        }

        public void publishAsync(URL url) {
            eventDeployer.publishEventAsync(new InstanceListener.InstanceEvent(url));
        }
    }
}
